#pragma once

#include <memory>
#include <vector>
#include <stdexcept>
#include "viml/lexer.h"
#include "viml/ast.h"

namespace viml {

// 递归下降语法分析器
class Parser {
private:
    std::vector<Token> tokens;
    size_t current;
    
    // 辅助方法
    Token peek() const;
    Token previous() const;
    bool is_at_end() const;
    bool check(TokenType type) const;
    bool check(const std::vector<TokenType>& types) const;
    bool match(TokenType type);
    bool match(const std::vector<TokenType>& types);
    Token advance();
    Token consume(TokenType type, const std::string& message);
    void skip_newlines();
    bool is_expression_start();
    std::unique_ptr<Expression> parse_full_expression();
    
    // 语法规则方法
    std::unique_ptr<Expression> expression();
    std::unique_ptr<Expression> logical_or();
    std::unique_ptr<Expression> logical_and();
    std::unique_ptr<Expression> equality();
    std::unique_ptr<Expression> comparison();
    std::unique_ptr<Expression> term();
    std::unique_ptr<Expression> factor();
    std::unique_ptr<Expression> unary();
    std::unique_ptr<Expression> call();
    std::unique_ptr<Expression> primary();
    std::unique_ptr<Expression> list_literal();
    std::unique_ptr<Expression> dict_literal();
    
    std::unique_ptr<Statement> statement();
    std::unique_ptr<Statement> let_statement();
    std::unique_ptr<Statement> echo_statement();
    std::unique_ptr<Statement> if_statement();
    std::unique_ptr<Statement> while_statement();
    std::unique_ptr<Statement> for_statement();
    std::unique_ptr<Statement> function_statement();
    std::unique_ptr<Statement> return_statement();
    
    std::vector<std::unique_ptr<Statement>> block();
    
    // 错误处理
    void error(const std::string& message);
    void synchronize();
    
public:
    explicit Parser(const std::vector<Token>& tokens);
    explicit Parser(const std::string& source);
    
    // 解析程序
    std::unique_ptr<Program> parse();
    
    // 解析单个表达式（用于测试）
    std::unique_ptr<Expression> parse_expression();
};

// 解析错误异常
class ParseError : public std::runtime_error {
public:
    size_t line;
    size_t column;
    
    ParseError(const std::string& message, size_t l, size_t c)
        : std::runtime_error(message), line(l), column(c) {}
};

} // namespace viml